let promise = new Promise((resolve, reject) => {
	resolve(1)
})
	.then((res) => {
		console.log(res)
		return new Promise((resolve, reject) => resolve(2))
	})
	.then((res) => {
		console.log(res)
		return new Promise((resolve, reject) => resolve(3))
	})
	.then((res) => {
		console.log(res)
		return new Promise((resolve, reject) => resolve(4))
	})
	.then((res) => {
		console.log(res)
		return new Promise((resolve, reject) => resolve(5))
	})
	.then((res) => {
		console.log(res)
		throw new Error('error')
		// return new Promise((resolve, reject) => resolve(6))
	})
	.then((res) => {
		console.log(res)
		return new Promise((resolve, reject) => resolve(7))
	})
	.then((res) => {
		console.log(res)
		return new Promise((resolve, reject) => resolve(8))
	})
	.catch((error) => {
		// * 以上任何一个 promise rejected（网络问题或者无效的 json 或其他），.catch 就会捕获它。
		console.log(error.message) // resolve is not defined
	})

// 执行结果：1 2 3 4 5 error

// **************************************************************************************************************

// * 隐式 try…catch
new Promise((resolve, reject) => {
	throw new Error('error')
}).catch(console.log) // error

// 两段代码相同。主动抛出错误或reject返回错误，效果是一样的：
new Promise((resolve, reject) => {
	reject(new Error('error'))
}).catch(console.log) // error

// **************************************************************************************************************

// * 任何错误都可以被尾部的 catch 捕获到

new Promise((resolve, reject) => {
	resolve('ok')
})
	.then((res) => {
		lalala // 未定义的变量
	})
	.catch((error) => {
		console.log(error) // ReferenceError: lalala is not defined
	})

// **************************************************************************************************************

// * .catch 捕获再次抛出的错误
new Promise((resolve, reject) => {
	throw new Error('error')
})
	.catch((error) => {
		if (error instanceof URIError) {
			// 处理这个错误
		} else {
			console.log('无法处理这个错误')
			// 再次抛出
			throw error
		}
	})
	.then(() => {
		// 这里不会运行
	})
	.catch((error) => {
		console.log('捕获再次抛出的错误：' + error)
	})

// 执行结果：1. 无法处理这个错误 2. 捕获再次抛出的错误：Error: error

// **************************************************************************************************************

// * 未处理的 rejection

new Promise((resolve, reject) => {
	throw new Error('error~')
}).then(() => {
	// 只有成功回调。没有 catch 失败回调（捕获错误，这种情况下可以在浏览器控制台中查看）
})

// * 或者在浏览器中可以使用，unhandledrejection 事件来捕获这类错误。
// * 如果出现了一个 error，并且在这没有 .catch，那么 unhandledrejection 处理程序就会被触发，并获取具有 error 相关信息的 event 对象，所以我们就能做一些后续处理了。
// * 它作为一个全局的错误处理机制，可以捕获代码中任何地方发生的未处理的 Promise 的错误。
window.addEventListener('unhandledrejection', function (event) {
	// 这个事件对象有两个特殊的属性：
	alert(event.promise) // [object Promise] —— 生成该全局 error 的 promise
	alert(event.reason) // Error: Whoops! —— 未处理的 error 对象
})

// **************************************************************************************************************

// * 总结：

// * 不使用 .catch 也可以。

// * 在任何情况下我们都应该有 unhandledrejection 事件处理程序（用于浏览器，以及其他环境的模拟），
// * 以跟踪未处理的 error 并告知用户（可能还有我们的服务器）有关信息，以使我们的应用程序永远不会“死掉”。

// * .catch 只能捕获 promise 中抛出的同步代码的错误（异步中的错误无法被捕获到）。
